﻿#include "stdafx.h"
#include "truetype.h"
#include "GdiRaster.h"
//#include <comdef.h>
//#include <GdiPlus.h>
//#ifndef ULONG_PTR
//typedef UINT_X ULONG_PTR;
//#endif
//#pragma comment(lib, "gdiplus.lib")
//using namespace Gdiplus;

const UINT_X WIDTH = 800;
const UINT_X HEIGHT = 600;
const char_x CLASS_NAME[] = _T("class_xujie");
const char_x WIND_NAME[] = _T("Test Venus Drawing");
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

HWND hWnd = NULL;
HINSTANCE hInst = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
	//_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); 
	//setlocale(0, "Chinese_People's Republic of China.936");
	hInst = (HINSTANCE)GetModuleHandle(NULL);

	WNDCLASSEX wcex;
	wcex.cbSize			= sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInst;
	wcex.hIcon			= LoadIcon(hInst, IDI_APPLICATION);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= CLASS_NAME;
	wcex.hIconSm		= wcex.hIcon;

	RegisterClassEx(&wcex);

	hWnd = CreateWindowEx(0, CLASS_NAME, WIND_NAME, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, WIDTH, HEIGHT, NULL, NULL, hInst, NULL);

	MoveWindow(hWnd, 100, 100, WIDTH + 8, HEIGHT + 32, FALSE);
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

HDC hBmpDc = NULL;
HBITMAP hBmp = NULL;
VOID OnCreate()
{
	HDC hdc = GetDC(NULL);
	BITMAPINFO bmpInfo = {0};
	bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmpInfo.bmiHeader.biWidth = WIDTH;
	bmpInfo.bmiHeader.biHeight = -((INT_32)HEIGHT);
	bmpInfo.bmiHeader.biPlanes = 1;
	bmpInfo.bmiHeader.biBitCount = 32;
	bmpInfo.bmiHeader.biCompression = BI_RGB;
	bmpInfo.bmiHeader.biSizeImage = WIDTH * HEIGHT * 4;
	uint_8 * bits = 0;
	hBmpDc = CreateCompatibleDC(NULL);
	hBmp = CreateDIBSection(hBmpDc, &bmpInfo, DIB_RGB_COLORS, (VOID **)&bits, NULL, 0);
	memset(bits, 0xFF, bmpInfo.bmiHeader.biSizeImage);
	SelectObject(hBmpDc, hBmp);

	truetype_t tt = {0};
	file_stream_t fs;
	create_file_stream(&fs, _T("font/msyh.ttf"));
	tt.stream = &fs.base;
	GdiRaster raster;
	GdiRasterReset(&raster, hBmpDc);
	tt.raster = &raster.base;
	// 简体中文
	tt.config.platform = tt_platform_microsoft;
	tt.config.language = tt_lang_ms_Chinese_Prc;
	tt.config.encoding = tt_enc_ms_unicode_ucs2;

	truetype_create(&tt);

	raster.x_rate = 12.0f / (tt.unit);
	raster.y_rate = raster.x_rate * -1.0f;
	raster.x_off = - tt.min_x * raster.x_rate;
	raster.y_off = -tt.ascent * raster.y_rate;

	wprintf(L"字体名称 ： %s\n", tt.family.family);
	wprintf(L"字体簇 ： %s\n", tt.family.sub_family);

	BeginPath(hBmpDc);

	tt_glyf_t glyf = {0};
	float_32 base = 0;
	for(int_32 cnt = 0; cnt != 10; ++cnt)
	{
		truetype_get_glyf(&tt, L'a' + cnt, &glyf);
		raster.x_off = (base - glyf.min_x + glyf.lsb) * raster.x_rate;
		truetype_raster_glyf(&tt, &glyf);
		//base += (glyf.max_x - glyf.min_x);
		base += glyf.ad_width;
	}
	truetype_get_glyf(&tt, L'\u00A5', &glyf);
	raster.x_off = (base - glyf.min_x) * raster.x_rate;
	truetype_raster_glyf(&tt, &glyf);
	base += (glyf.max_x - glyf.min_x);

	EndPath(hBmpDc);
	HBRUSH brush = CreateSolidBrush(0x0);
	HGDIOBJ old = SelectObject(hBmpDc, brush);
	SetPolyFillMode(hBmpDc, WINDING);
	FillPath(hBmpDc);
	//StrokePath(hBmpDc);

	truetype_destroy(&tt);
	destroy_file_stream(&fs);

	TextOutW(hBmpDc, 0, 200, L"abcdefg", 7);
}

VOID OnDestroy()
{
	DeleteDC(hBmpDc);
	DeleteObject(hBmp);
}

VOID OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps = {0};
	HDC hdc = BeginPaint(hWnd, &ps);
	BitBlt(hdc, 0, 0, WIDTH, HEIGHT, hBmpDc, 0, 0, SRCCOPY);
	EndPaint(hWnd, &ps);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_LBUTTONDOWN:
		SetCapture(hWnd);
		break;
	case WM_LBUTTONUP:
		ReleaseCapture();
		break;
	case WM_KILLFOCUS:
		break;
	case WM_RBUTTONDOWN:
		break;
	case WM_MOUSEMOVE:
		break;
	case WM_ERASEBKGND:
		break;
	case WM_CREATE:
		OnCreate();
		break;
	case WM_DESTROY:
		OnDestroy();
		PostQuitMessage(0);
		break;
	case WM_PAINT:
		OnPaint(hWnd);
		break;
	case WM_KEYDOWN:
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
